package com.module.umlib.wx;

import android.text.TextUtils;
import android.widget.Toast;

import com.module.umlib.WXHelper;
import com.module.umlib.utils.Accept;
import com.module.umlib.utils.ConstantsUtils;
import com.module.umlib.wxlistener.OnWxLoginListener;
import com.module.umlib.wxlistener.OnWxPayListener;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelpay.PayReq;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;

import java.lang.reflect.Field;
import java.util.LinkedHashMap;
import java.util.Map;

import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentManager;
import io.reactivex.Observable;
import io.reactivex.subjects.BehaviorSubject;

/**
 * 微信授权登录内存泄露问题
 * https://blog.csdn.net/weixin_34402090/article/details/89589965
 *
 */
public class WXFragment extends Fragment {

    private static String TAG = "WXFragment";
    private static BehaviorSubject<Accept> mObservable;
    private IWXAPI wxAPI;


    public static WXFragment newInstance(FragmentActivity activity) {
        FragmentManager fragmentManager = activity.getSupportFragmentManager();

        WXFragment wXFragment = (WXFragment) fragmentManager.findFragmentByTag(TAG);
        boolean isNewInstance = wXFragment == null;
        if (isNewInstance) {
            wXFragment = new WXFragment();
            fragmentManager
                    .beginTransaction()
                    .add(wXFragment, TAG)
                    .commitAllowingStateLoss();
            fragmentManager.executePendingTransactions();
        }

        return wXFragment;
    }

    public IRxWX createObservable() {
        mObservable = BehaviorSubject.create();
        return new IRxWX() {

            @Override
            public Observable<Accept> wxAuthLogin() {
                WXHelper.onWxLoginListener = new OnWxLoginListener() {
                    @Override
                    public void onComplete(String code) {
                        mObservable.onNext(new Accept(ConstantsUtils.Complete, code));
                    }

                    @Override
                    public void onCancel() {
                        mObservable.onNext(new Accept(ConstantsUtils.Cancel));
                    }

                    @Override
                    public void onFailed() {
                        mObservable.onNext(new Accept(ConstantsUtils.Failed));
                    }
                };
                //发送登录请求
                sendWXLogin();
                return mObservable;
            }

            @Override
            public Observable<Accept> wxPayment(LinkedHashMap<String, String> result) {
                WXHelper.onWxPayListener = new OnWxPayListener() {
                    @Override
                    public void onComplete() {
                        mObservable.onNext(new Accept(ConstantsUtils.Complete));
                    }

                    @Override
                    public void onCancel() {
                        mObservable.onNext(new Accept(ConstantsUtils.Cancel));
                    }

                    @Override
                    public void onFailed() {
                        mObservable.onNext(new Accept(ConstantsUtils.Failed));
                    }
                };
                //发送支付请求
                sendWXPay(result);
                return mObservable;
            }
        };
    }


    /**
     * 微信原生登录 获取code
     */
    private void sendWXLogin() {
        wxAPI = WXAPIFactory.createWXAPI(getContext(), null);
        if (!wxAPI.isWXAppInstalled()) {
            Toast.makeText(getContext(), "您还未安装微信客户端!", Toast.LENGTH_SHORT).show();
            return;
        }
        wxAPI.registerApp(ConstantsUtils.WX_APP_ID);
        //微信登录
        SendAuth.Req req = new SendAuth.Req();
        req.scope = "snsapi_userinfo";
        req.state = "wechat_sdk_demo_test";
        wxAPI.sendReq(req);
    }


    /**
     * 微信支付
     *
     * @param result
     */
    private void sendWXPay(LinkedHashMap<String, String> result) {
        IWXAPI wxAPI = WXAPIFactory.createWXAPI(getContext(), null);
        if (!wxAPI.isWXAppInstalled()) {
            Toast.makeText(getContext(), "您还未安装微信客户端!", Toast.LENGTH_SHORT).show();
            return;
        } else if (result == null) {
            Toast.makeText(getContext(), "支付信息有误!", Toast.LENGTH_SHORT).show();
            return;
        } else if (TextUtils.isEmpty(result.get("appid"))) {
            Toast.makeText(getContext(), "微信参数有误!", Toast.LENGTH_SHORT).show();
            return;
        }
        wxAPI.registerApp(result.get("appid"));
        PayReq req = new PayReq();
        req.appId = result.get("appid");
        req.nonceStr = result.get("noncestr");
        req.packageValue = result.get("package");
        req.partnerId = result.get("partnerid");
        req.prepayId = result.get("prepayid");
        req.timeStamp = result.get("timestamp");
        req.sign = result.get("sign");
        wxAPI.sendReq(req);
    }

    /**
     * 清除微信memory leak
     */
    public static void cleanWXLeak() {
        try {
            Class clazz = com.tencent.a.a.a.a.g.class;
            Field field = clazz.getDeclaredField("V");
            field.setAccessible(true);
            Object obj = field.get(clazz);
            if (obj != null) {
                com.tencent.a.a.a.a.g g = (com.tencent.a.a.a.a.g) obj;
                Field mapField = clazz.getDeclaredField("U");
                mapField.setAccessible(true);
                Map map = (Map) mapField.get(g);
                map.clear();
            }
            field.set(clazz, null);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onDestroy() {
        wxAPI.detach();
        cleanWXLeak();
        WXHelper.onWxLoginListener = null;
        WXHelper.onWxPayListener = null;
        super.onDestroy();
    }
}
